(function() {
	var browser = baidu.editor.browser, domUtils = baidu.editor.dom.domUtils, uiUtils = baidu.editor.ui.uiUtils;

	var TPL_STATEFUL = 'onmousedown="$$.Stateful_onMouseDown(event, this);"'
			+ ' onmouseup="$$.Stateful_onMouseUp(event, this);"'
			+ (browser.ie
					? (' onmouseenter="$$.Stateful_onMouseEnter(event, this);"' + ' onmouseleave="$$.Stateful_onMouseLeave(event, this);"')
					: (' onmouseover="$$.Stateful_onMouseOver(event, this);"' + ' onmouseout="$$.Stateful_onMouseOut(event, this);"'));

	baidu.editor.ui.Stateful = {
		alwalysHoverable : false,
		Stateful_init : function() {
			this._Stateful_dGetHtmlTpl = this.getHtmlTpl;
			this.getHtmlTpl = this.Stateful_getHtmlTpl;
		},
		Stateful_getHtmlTpl : function() {
			var tpl = this._Stateful_dGetHtmlTpl();
			// 使用function避免$转义
			return tpl.replace(/stateful/g, function() {
						return TPL_STATEFUL;
					});
		},
		Stateful_onMouseEnter : function(evt, el) {
			if (!this.isDisabled() || this.alwalysHoverable) {
				this.addState('hover');
				this.fireEvent('over');
			}
		},
		Stateful_onMouseLeave : function(evt, el) {
			if (!this.isDisabled() || this.alwalysHoverable) {
				this.removeState('hover');
				this.removeState('active');
				this.fireEvent('out');
			}
		},
		Stateful_onMouseOver : function(evt, el) {
			var rel = evt.relatedTarget;
			if (!uiUtils.contains(el, rel) && el !== rel) {
				this.Stateful_onMouseEnter(evt, el);
			}
		},
		Stateful_onMouseOut : function(evt, el) {
			var rel = evt.relatedTarget;
			if (!uiUtils.contains(el, rel) && el !== rel) {
				this.Stateful_onMouseLeave(evt, el);
			}
		},
		Stateful_onMouseDown : function(evt, el) {
			if (!this.isDisabled()) {
				this.addState('active');
			}
		},
		Stateful_onMouseUp : function(evt, el) {
			if (!this.isDisabled()) {
				this.removeState('active');
			}
		},
		Stateful_postRender : function() {
			if (this.disabled && !this.hasState('disabled')) {
				this.addState('disabled');
			}
		},
		hasState : function(state) {
			return domUtils.hasClass(this.getStateDom(), 'edui-state-' + state);
		},
		addState : function(state) {
			if (!this.hasState(state)) {
				this.getStateDom().className += ' edui-state-' + state;
			}
		},
		removeState : function(state) {
			if (this.hasState(state)) {
				domUtils.removeClasses(this.getStateDom(), ['edui-state-'
								+ state]);
			}
		},
		getStateDom : function() {
			return this.getDom('state');
		},
		isChecked : function() {
			return this.hasState('checked');
		},
		setChecked : function(checked) {
			if (!this.isDisabled() && checked) {
				this.addState('checked');
			} else {
				this.removeState('checked');
			}
		},
		isDisabled : function() {
			return this.hasState('disabled');
		},
		setDisabled : function(disabled) {
			if (disabled) {
				this.removeState('hover');
				this.removeState('checked');
				this.removeState('active');
				this.addState('disabled');
			} else {
				this.removeState('disabled');
			}
		}
	};
})();
